package com.cqfae.deploycentral.app.utils;

import com.cqfae.deploycentral.app.base.BaseConstants;
import com.cqfae.deploycentral.app.dao.entity.ApproveDocument;
import com.cqfae.deploycentral.app.web.response.IPage;
import com.cqfae.deploycentral.app.web.vo.*;
import com.github.pagehelper.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static com.cqfae.deploycentral.app.base.BaseConstantCode.APPROVE_STATUS_FAIL_CODE;
import static com.cqfae.deploycentral.app.base.BaseConstantCode.APPROVE_STATUS_SUCCESS_CODE;

@Component
public class ConvertUtil {

    private static final String STR_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    private static final String RELEASE_DATE_FORMAT = "yyyy-MM-dd";
    private static final String WINDOW_DATE_FORMAT = "yyyyMMdd";

    private static final String AUTO_TITLE = "【标题】\n";
    private static final String AUTO_BOTTON = "此邮件由【部署中心】自动发送，请勿直接回复此邮件！";

    private static Logger logger = LoggerFactory.getLogger(ConvertUtil.class);


    private ConvertUtil() {

    }

    /**
     * 生成jenkins 发布远程访问url
     *
     * @param vo
     * @return
     */
    public static String createJenkinsRemoteUrl(JenkinsRemoteVo vo) {
        StringBuilder sbd = new StringBuilder(vo.getJenkinsHost() + vo.getJenkinsBuildUrl());
        //String callBackMethod = String.format(vo.getCallBackMethod());
        sbd.append("?token=" + vo.getToken());
        //sbd.append("&env=" + vo.getEnv());
        sbd.append("&tag=" + vo.getTag());
        sbd.append("&callBackId=" + vo.getCallBackId());
        sbd.append("&callBackHost=" + vo.getCallBackHost());
        //sbd.append("&callBackMethod=" + callBackMethod);
        sbd.append("&appCheckUrl=" + vo.getAppCheckUrl());
        sbd.append("&appPort=" + vo.getAppPort());
        sbd.append("&action=" + vo.getAction());
        return sbd.toString();
    }

    /**
     * @param jenkinsHost
     * @param appName
     * @param buildId
     * @return
     */
    public static String createJenkinsLogUrl(String jenkinsHost, String appName, Integer buildId) {
        StringBuilder sbd = new StringBuilder(jenkinsHost + "/job/" + appName + "/" + buildId);
        sbd.append("/logText/progressiveText?start=0");
        return sbd.toString();
    }

    // 日期类型的转换

    public static Date convertSTD(String date) {
        try {
            return new SimpleDateFormat(STR_DATE_FORMAT).parse(date);
        } catch (ParseException e) {
            logger.error("ERROR:{}", e);
        }
        return null;
    }

    public static String convertDTS(Date date) {
        return new SimpleDateFormat(STR_DATE_FORMAT).format(date);
    }

    public static String convertDJTS(Date date) {
        return new SimpleDateFormat(RELEASE_DATE_FORMAT).format(date);
    }

    public static String convertDSTS(Date date) {
        return new SimpleDateFormat(WINDOW_DATE_FORMAT).format(date);
    }

    /**
     * @param <E>
     * @param @param  page
     * @param @param  ipage
     * @param @return
     * @return IPage<?>
     * @throws
     * @Title: pageToIpage
     */
    public static <E> IPage<E> pageToIpage(Page<?> page, IPage<E> ipage) {
        try {
            BeanUtils.copyProperties(page,ipage);
        } catch (Exception e) {
            logger.error("ERROR:{}", e);
        }
        return ipage;
    }

    /**
     * 判断一个数值所在范围
     *
     * @param current
     * @param min
     * @param max
     * @return
     */
    public static boolean rangeInDefined(int current, int min, int max) {
        return Math.max(min, current) == Math.min(current, max);
    }

    public static int minByParentCode(Integer parentCode) {
        return Integer.parseInt(parentCode.toString() + "000");
    }

    public static int maxByParentCode(Integer parentCode) {
        return Integer.parseInt(parentCode.toString() + "999");
    }

    /**
     * @param vo
     * @return
     */
    public static String getMailContent(ReportInfoVo vo) {
        StringBuilder sbd = new StringBuilder();
        if (NullUtil.isNotEmpty(vo.getTitle())) {
            sbd.append(AUTO_TITLE);
            sbd.append(vo.getTitle() + "\n");
        }
        if (NullUtil.isNotEmpty(vo.getReportResult())) {
            sbd.append("【测试结论】\n");
            sbd.append(vo.getReportResult() + "\n");
        }
        if (vo.getReportTestLinkVoList() != null && !vo.getReportTestLinkVoList().isEmpty()) {
            for (ReportTestLinkVo reportTestLinkVo : vo.getReportTestLinkVoList()) {
                sbd.append("【测试计划】\n");
                sbd.append("系统名称：" + reportTestLinkVo.getTprjname() + "  版本：" + reportTestLinkVo.getVersionName() + "\n");
            }
        }
        if (NullUtil.isNotEmpty(vo.getRequires())) {
            sbd.append("【需求结果汇总】\n");
            for (ReportRequireVo reqs : vo.getRequires()) {
                sbd.append(reqs.getTesters() + "，" + reqs.getRequireInfo() + "，" + BaseConstants.getConstantsCodeMap().get(String.valueOf(reqs.getCheckStatus())) + "，" + reqs.getProductCheck() + "\n");
            }
        }
        if (NullUtil.isNotEmpty(vo.getSitResult())) {
            sbd.append("【功能测试结果汇总】\n");
            sbd.append(vo.getSitTimeStart() + " 至 " + vo.getSitTimeEnd() + "  功能测试结论： " + vo.getSitResult() + "\n");
        }
        if (NullUtil.isNotEmpty(vo.getRetResult())) {
            sbd.append("【回归测试结果汇总】\n");
            sbd.append(vo.getRetTimeStart() + " 至 " + vo.getRetTimeEnd() + "  回归测试结论： " + vo.getRetResult() + "\n");
        }
        if (NullUtil.isNotEmpty(vo.getUatResult())) {
            sbd.append("【用户验收测试(UAT结果汇总)】\n");
            sbd.append(vo.getUatTimeStart() + " 至 " + vo.getUatTimeEnd() + "  用户验收测试结论： " + vo.getUatResult() + "\n");
        }
        if (NullUtil.isNotEmpty(vo.getBugRemark())) {
            sbd.append("【Bug概述】\n");
            sbd.append(vo.getBugRemark() + "\n");
        }
        if (NullUtil.isNotEmpty(vo.getReportInfoTagsVoList())) {
            sbd.append("【测试通过的Tag信息】\n");
            for (ReportInfoTagVo tag : vo.getReportInfoTagsVoList()) {
                sbd.append("应用名称：" + tag.getAppName() + "  TAG：" + tag.getTagInfo() + "  优先级：" + tag.getLevel() + "\n");
            }
        }
        sbd.append("--------------详情请参考部署中心【测试报告】---------------\n");
        sbd.append(AUTO_BOTTON);
        return sbd.toString();
    }

    /**
     * 发送审批邮件
     *
     * @param approveDocument
     * @return
     */
    public static String getMailContentForApproveResult(ApproveDocument approveDocument) {
        StringBuilder sbd = new StringBuilder();
        if (NullUtil.isNotEmpty(approveDocument.getJiraVersionName()) && NullUtil.isNotEmpty(approveDocument.getApproveStatus())) {
            sbd.append("您好\n");
            if (APPROVE_STATUS_SUCCESS_CODE == approveDocument.getApproveStatus()) {
                sbd.append("\t\t您提交的项目:");
                sbd.append(approveDocument.getJiraVersionName());
                sbd.append("\t的评审文档已评审通过。\n");
            }
            if (APPROVE_STATUS_FAIL_CODE == approveDocument.getApproveStatus()) {
                sbd.append("\t\t您提交的项目:");
                sbd.append(approveDocument.getJiraVersionName());
                sbd.append("\t的评审文档已评审未通过，请重新提交。\n");
            }
        }
        sbd.append("--------------详情请参考部署中心【提交评审】---------------\n");
        sbd.append(AUTO_BOTTON);
        return sbd.toString();
    }

    /**
     * 发送审批邮件
     *
     * @param approveDocument
     * @return
     */
    public static String getMailContentForNoticApprove(ApproveDocument approveDocument) {
        StringBuilder sbd = new StringBuilder();
        if (NullUtil.isNotEmpty(approveDocument.getJiraVersionName())) {
            sbd.append("您好\n");
            sbd.append(approveDocument.getCommitBy());
            sbd.append("\t提交了项目：");
            sbd.append(approveDocument.getJiraVersionName());
            sbd.append("\t的待评审文件，请评审。\n");
        }
        sbd.append("--------------详情请参考部署中心【上线评审】---------------\n");
        sbd.append(AUTO_BOTTON);
        return sbd.toString();
    }

    /**
     * @param year
     * @param month
     * @return
     */
    public static List<Date> getWorkDates(int year, int month) {
        List<Date> dates = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DATE, 1);
        while (cal.get(Calendar.YEAR) == year &&
                cal.get(Calendar.MONTH) < month) {
            int day = cal.get(Calendar.DAY_OF_WEEK);
            if (!(day == Calendar.SUNDAY || day == Calendar.SATURDAY)) {
                dates.add((Date) cal.getTime().clone());
            }
            cal.add(Calendar.DATE, 1);
        }
        return dates;
    }

    public static Calendar checkNextWorkDay(Calendar calendar) {
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        if (!(day == Calendar.SUNDAY || day == Calendar.SATURDAY)) {
            return calendar;
        } else {
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);
            return checkNextWorkDay(calendar);
        }
    }

    /**
     * 下载文件流
     *
     * @param fileName
     * @param file
     * @param length
     * @param response
     */
    public void outputResponse(String fileName, File file, int length, HttpServletResponse response) {
        response.addHeader("Content-Type", "application/octet-stream");
        response.addHeader("Content-Type", "text/html; charset=utf-8");
        try {
            response.addHeader("Content-Disposition", "attachment;filename=" +
                    new String(fileName.getBytes("UTF-8"), "iso-8859-1"));
        } catch (UnsupportedEncodingException e) {
            logger.error("outputResponse UnsupportedEncodingException", e);
        }
        byte[] buff = new byte[length];
        try (
                FileInputStream in = new FileInputStream(file);
                OutputStream os = response.getOutputStream();
                BufferedInputStream bis = new BufferedInputStream(in);
        ) {
            while (bis.read(buff) != -1) {
                os.write(buff, 0, buff.length);
                os.flush();
            }
        } catch (IOException e) {
            logger.error("outputResponse IOException", e);
        }
    }
}
